package com.luoyx.vjsb.authority.security.manager;

import cn.hutool.core.util.StrUtil;
import com.luoyx.vjsb.authority.util.SecurityUtil;
import com.luoyx.vjsb.authority.util.UserUtil;
import com.luoyx.vjsb.core.entity.SysUser;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Component;
import org.springframework.util.PathMatcher;

import javax.annotation.Resource;
import java.util.*;

/**
 * <p>
 * 权限加载
 * </p>
 *
 * @author luoyuanxiang
 * @date 2020/5/4 17:07
 */
@Component
public class MySecurityMetadataSource implements FilterInvocationSecurityMetadataSource {

    @Resource
    private SecurityUtil securityUtil;

    @Resource
    private PathMatcher pathMatcher;

    private Map<String, Collection<ConfigAttribute>> map = null;

    /**
     * 加载权限表中所有操作请求权限
     */
    public void loadResourceDefine(){

        map = new HashMap<>(16);
        Collection<ConfigAttribute> configAttributes;
        ConfigAttribute cfg;
        SysUser currUser = securityUtil.getCurrUser();
        // 获取启用的权限操作请求
        Set<String> permissions = UserUtil.getPermissions(currUser);
        assert permissions != null;
        Iterator<String> iterator = permissions.iterator();
        while (iterator.hasNext()) {
            configAttributes = new ArrayList<>();
            cfg = new SecurityConfig(iterator.next());
            //作为MyAccessDecisionManager类的decide的第三个参数
            configAttributes.add(cfg);
            //用权限的path作为map的key，用ConfigAttribute的集合作为value
            map.put(iterator.next(), configAttributes);
        }
    }

    /**
     * 判定用户请求的url是否在权限表中
     * 如果在权限表中，则返回给decide方法，用来判定用户是否有此权限
     * 如果不在权限表中则放行
     * @param o 1
     * @return 1
     * @throws IllegalArgumentException 1
     */
    @Override
    public Collection<ConfigAttribute> getAttributes(Object o) throws IllegalArgumentException {

        if(map == null){
            loadResourceDefine();
        }
        // Object中包含用户请求request
        String url = ((FilterInvocation) o).getRequestUrl();
        for (String resurl : map.keySet()) {
            if (StrUtil.isNotBlank(resurl) && pathMatcher.match(resurl, url)) {
                return map.get(resurl);
            }
        }
        return null;
    }

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return true;
    }
}
